﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _12_Task_常用操作
{
    public partial class Form1 : Form
    {
        //取消线程的时候发送通知，此类内部自带Lock不用担心线程安全问题
        CancellationTokenSource cts;
        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 启动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            cts = new CancellationTokenSource();//实例化线程取消通知
            foreach (Control item in this.tableLayoutPanel1.Controls)
            {
                if (item is ProgressBar progressBar)
                {
                    Task.Run(() => 
                    {
                        try
                        {
                            for (int i = 0; i <= 100; i++)
                            {
                                //这个窗体控件是属于UI线程创建的，不能直接访问。必须通过委托才能访问
                                //在Form窗体中，有一个方法Invoke，可以帮助我们实现跨线程访问
                                //.NET 机制要求，不能在非创建控件的线程上访问控件
                                //this.Invoke(new Action(() => { }));//跨线程访问访问
                                this.Invoke(new Action(() => 
                                {
                                    progressBar.Value = i;
                                }));
                                if (cts.Token.IsCancellationRequested)//判断是否取消
                                {
                                    break;//退出当前循环
                                }
                                Thread.Sleep(15);
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    });
                }
            }
        }
        /// <summary>
        /// 终止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            cts.Cancel();//发出取消通知
        }
        
        /// <summary>
        /// 线程阻塞
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            Task.Run(() => 
            {
                cts = new CancellationTokenSource();//实例化线程取消通知
                foreach (Control item in this.tableLayoutPanel1.Controls)
                {
                    if (item is ProgressBar progressBar)
                    {
                        Task task = Task.Run(() =>
                        {
                            try
                            {
                                for (int i = 0; i <= 100; i++)
                                {
                                    //这个窗体控件是属于UI线程创建的，不能直接访问。必须通过委托才能访问
                                    //在Form窗体中，有一个方法Invoke，可以帮助我们实现跨线程访问
                                    //.NET 机制要求，不能在非创建控件的线程上访问控件
                                    //this.Invoke(new Action(() => { }));//跨线程访问访问
                                    this.Invoke(new Action(() =>
                                    {
                                        progressBar.Value = i;
                                    }));
                                    if (cts.Token.IsCancellationRequested)//判断是否取消
                                    {
                                        break;//退出当前循环
                                    }
                                    Thread.Sleep(15);
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                            }
                        });
                        task.Wait();//阻塞当前线程，直到task执行完毕
                    }
                }                
            });
        }
        /// <summary>
        /// 后继线程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            this.button3.Enabled = false;
            //ContinueWith可以继续执行的任务
            Task.Run(() =>
            {
                cts = new CancellationTokenSource();//实例化线程取消通知
                foreach (Control item in this.tableLayoutPanel1.Controls)
                {
                    if (item is ProgressBar progressBar)
                    {
                        Task task = Task.Run(() =>
                        {
                            try
                            {
                                for (int i = 0; i <= 100; i++)
                                {
                                    //这个窗体控件是属于UI线程创建的，不能直接访问。必须通过委托才能访问
                                    //在Form窗体中，有一个方法Invoke，可以帮助我们实现跨线程访问
                                    //.NET 机制要求，不能在非创建控件的线程上访问控件
                                    //this.Invoke(new Action(() => { }));//跨线程访问访问
                                    this.Invoke(new Action(() =>
                                    {
                                        progressBar.Value = i;
                                    }));
                                    if (cts.Token.IsCancellationRequested)//判断是否取消
                                    {
                                        break;//退出当前循环
                                    }
                                    Thread.Sleep(15);
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                            }
                        });
                        task.Wait();//阻塞当前线程，直到task执行完毕
                    }
                }
            }).ContinueWith(t=>
            {
                this.Invoke(new Action(() => { this.button3.Enabled = true; }));
            });
        }
    }
}
